package com.vanysoft.business.base.org.controller;

import com.vanysoft.business.base.org.controller.demo.OrgDemo;
import com.vanysoft.business.base.org.service.BaseOrgService;
import com.vanysoft.business.sys.entity.UserInfo;
import com.vanysoft.common.utils.Excel.ExcelUtil;
import com.vanysoft.common.utils.string.StringUtil;
import com.vanysoft.framework.aop.VanySoftValidation;
import com.vanysoft.framework.aop.VanySoftValidationException;
import com.vanysoft.framework.base.action.BaseController;
import com.vanysoft.framework.config.mvc.SessionUser;
import com.vanysoft.framework.constants.DbConstants;
import com.vanysoft.framework.exception.VanySoftBaseException;
import com.vanysoft.framework.messagesource.MessageCodeConstant;
import com.vanysoft.framework.utils.JSONResponse;
import com.vanysoft.framework.validation.VanySoftValidationErr;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.*;

/**
 * 类名称：BaseOrgAction
 * 类描述：组织机构类
 * 创建人：SharpClaw_x
 * 创建时间：2017年5月19日 下午12:00:11
 * 修改人：Tian_
 * 修改时间：2017年5月19日 下午12:00:11
 * 版本信息：@version 1.0
 * Copyright (c) 2017SharpClaw-版权所有
 * 修改备注：
 */

@RestController
@RequestMapping("/base/org")
public class BaseOrgAction extends BaseController {

    @Autowired
    private BaseOrgService orgService;

    /**
     * Function Name               addOrg
     *
     * @return
     * @throws VanySoftBaseException
     * @description 新增一个组织机构
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年5月19日 下午1:51:04           SharpClaw_x      Initial
     * *********************************************************************
     */
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    @VanySoftValidation
    public JSONResponse addOrg(HttpServletRequest request, @Valid OrgDemo org, BindingResult result) throws VanySoftBaseException {
        orgService.addOrg(org);
        return new JSONResponse();
    }

    /**
     * Function Name               queryOrgTree
     *
     * @return
     * @throws VanySoftBaseException
     * @description 查询组织机构树
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年5月23日 下午6:12:24           SharpClaw_x      Initial
     * *********************************************************************
     */
    @SuppressWarnings("rawtypes")
    @RequestMapping(value = "/queryOrgTree", method = RequestMethod.GET)
    public JSONResponse queryOrgTree(@SessionUser UserInfo userInfo) throws VanySoftBaseException {
        List<Map> tree = orgService.queryOrgTree(userInfo.getId());
        return new JSONResponse(MessageCodeConstant.RTN_CODE_SUCCESS, tree);
    }

    /**
     * Function Name               queryOrgTreeWithOutSelf
     *
     * @param request
     * @param orgCode
     * @return
     * @description 查询除了所点击部门的其他部门树
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年7月4日 下午5:27:58           SharpClaw_x      Initial
     * *********************************************************************
     */
    @RequestMapping(value = "queryOrgTreeWithOutSelf", method = RequestMethod.GET)
    public JSONResponse queryOrgTreeWithOutSelf(@SessionUser UserInfo userInfo, HttpServletRequest request, String orgCode) {
        String userId = userInfo.getId();
        List<Map> tree = orgService.queryOrgTreeWithOutSelf(userId, orgCode);
        return new JSONResponse(MessageCodeConstant.RTN_CODE_SUCCESS, tree);
    }

    /**
     * Function Name               checkOrgCode
     *
     * @param request
     * @param orgCode
     * @return
     * @throws VanySoftBaseException
     * @description 检查组织机构代码是否重复
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年5月23日 下午6:12:34           SharpClaw_x      Initial
     * *********************************************************************
     */
    @RequestMapping(value = "/checkOrgCode", method = RequestMethod.GET)
    public JSONResponse checkOrgCode(HttpServletRequest request, String orgCode) throws VanySoftBaseException {
        String rspCode = MessageCodeConstant.RTN_CODE_SUCCESS;
        if (orgService.checkOrgCode(orgCode)) {
            rspCode = MessageCodeConstant.OrgException.EXIST_ERROR;
        }
        return new JSONResponse(rspCode);
    }

    /**
     * Function Name               updateOrg
     *
     * @param request
     * @param org
     * @return
     * @throws VanySoftBaseException
     * @description 修改组织机构
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年5月23日 下午6:12:50           SharpClaw_x      Initial
     * *********************************************************************
     */
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    @VanySoftValidation
    public JSONResponse updateOrg(HttpServletRequest request, @Valid OrgDemo org, BindingResult result) throws VanySoftBaseException {
        String rspCode = orgService.updateOrg(org);
        return new JSONResponse(rspCode);
    }

    /**
     * Function Name               updateOrgToRoot
     *
     * @return
     * @throws VanySoftBaseException
     * @description 将节点修改为根节点
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年7月10日 上午10:24:10           SharpClaw_x      Initial
     * *********************************************************************
     */
    @RequestMapping(value = "/updateToRoot", method = RequestMethod.POST)
    public JSONResponse updateOrgToRoot(String orgCode) throws VanySoftBaseException {
        orgService.updateOrgRoot(orgCode);
        return new JSONResponse();
    }

    /**
     * Function Name               deleteOrg
     *
     * @param orgCode
     * @return
     * @throws VanySoftBaseException
     * @description 删除组织机构
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年5月23日 下午6:13:01           SharpClaw_x      Initial
     * *********************************************************************
     */
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    public JSONResponse deleteOrg(String orgCode) throws VanySoftBaseException {
        String rspCode = orgService.deleteOrg(orgCode);
        return new JSONResponse(rspCode);
    }

    /**
     * Function Name               sortOrg
     *
     * @param orgCode
     * @param action：UP/DOWM
     * @return
     * @throws VanySoftBaseException
     * @description 上下移动
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年5月23日 下午7:45:19           SharpClaw_x      Initial
     * *********************************************************************
     */
    @RequestMapping(value = "/updateOrderNum", method = RequestMethod.POST)
    public JSONResponse sortOrg(String orgCode, String action) throws VanySoftBaseException {
        String rspCode = null;
        if (StringUtil.equals(action, DbConstants.ORG_UP)) {
            rspCode = orgService.upOrg(orgCode);
        } else if (StringUtil.equals(action, DbConstants.ORG_DOWN)) {
            rspCode = orgService.downOrg(orgCode);
        }
        return new JSONResponse(rspCode);
    }

    /**
     * Function Name               queryOrgUserList
     *
     * @param request
     * @param orgCode
     * @param pageSize
     * @return
     * @throws NumberFormatException
     * @throws VanySoftBaseException
     * @description 查询组织机构下的人员
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年5月24日 下午2:15:32           SharpClaw_x      Initial
     * *********************************************************************
     */
    @RequestMapping(value = "/queryOrgUserList", method = RequestMethod.GET)
    public JSONResponse queryOrgUserList(@SessionUser UserInfo userInfo, HttpServletRequest request, String orgCode, String pageSize, String pageIndex, String searchValue, String status) throws NumberFormatException, VanySoftBaseException {

        Integer _pageIndex = StringUtil.isEmpty(pageIndex) ? 1 : Integer.valueOf(pageIndex);
        Integer _pageSize = StringUtil.isEmpty(pageSize) ? 20 : Integer.valueOf(pageSize);


        Map<String, Object> map = new HashMap<String, Object>();

        if (userInfo != null) {
            map = orgService.queryOrgUsers(orgCode, userInfo.getId(), _pageSize, _pageIndex, searchValue, status);
        }

        return new JSONResponse(MessageCodeConstant.RTN_CODE_SUCCESS, map);
    }

    /**
     * Function Name               queryOrgUserForSort
     *
     * @param request
     * @param orgCode
     * @return
     * @description 查询机构下人员供排序
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年7月5日 上午10:21:44           SharpClaw_x      Initial
     * *********************************************************************
     */
    @RequestMapping(value = "/queryOrgUserForSort", method = RequestMethod.GET)
    public JSONResponse queryOnlyOrgUsers(HttpServletRequest request, String orgCode) {

        List<Map<String, Object>> orgUsers = orgService.queryOnlyOrgUsers(orgCode);

        return new JSONResponse(orgUsers);
    }

    /**
     * Function Name               queryUserInfo
     *
     * @param request
     * @return
     * @throws VanySoftBaseException
     * @description 查询个人信息
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年6月7日 下午6:53:33           SharpClaw_x      Initial
     * *********************************************************************
     */
    @RequestMapping(value = "/queryUserInfo", method = RequestMethod.GET)
    public JSONResponse queryUserInfo(@SessionUser UserInfo userInfo, HttpServletRequest request, String userId) throws VanySoftBaseException {
        Map<String, Object> user = orgService.queryUserInfo(userId, userInfo);
        return new JSONResponse(MessageCodeConstant.RTN_CODE_SUCCESS, user);
    }

    /**
     * Function Name               excelImportOrg
     *
     * @param request
     * @param file
     * @return
     * @throws InvalidFormatException
     * @throws IOException
     * @throws VanySoftBaseException
     * @description Excel导入组织机构
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年6月8日 下午2:26:05           SharpClaw_x      Initial
     * *********************************************************************
     */
    @RequestMapping(value = "/import", method = RequestMethod.POST)
    public JSONResponse excelImportOrg(HttpServletRequest request, MultipartFile file) throws VanySoftBaseException {
        //都能实现
        Workbook workbook = ExcelUtil.createByFactory(file);

        Sheet sheet = workbook.getSheetAt(0);

        if (sheet != null) {
            //移除第一行标题行
            sheet.removeRow(sheet.getRow(0));
            List<Row> list = ExcelUtil.readExcelContent(sheet);

            List<Map<String, Object>> orgList = orgService.queryAllOrgCode();
            Set<String> databaseOrg = new HashSet<String>();

            for (Map<String, Object> org : orgList) {
                if (StringUtils.isNotEmpty(String.valueOf(org.get("orgCode")))) {
                    databaseOrg.add(String.valueOf(org.get("orgCode")));
                }
            }

            String orgCode = null;
            String orgName = null;
            String parnetCode = null;
            String officeTel = null;
            List<OrgDemo> orgDemos = new ArrayList<OrgDemo>();
            List<String> excelOrg = new ArrayList<String>();
            Set<String> excelParent = new HashSet<String>();

            List<String> contentVal = new ArrayList<String>();
            for (Row row : list) {
                OrgDemo demo = new OrgDemo();
                String result = "第" + (row.getRowNum() + 1) + "行：";

                orgCode = ExcelUtil.getCellValue(row.getCell(0)).trim();
                if (StringUtils.isNotEmpty(orgCode)) {
                    excelOrg.add(orgCode);
                }

                parnetCode = ExcelUtil.getCellValue(row.getCell(2)).trim();
                if (StringUtils.isNotEmpty(parnetCode)) {
                    excelParent.add(parnetCode);
                }

                orgName = ExcelUtil.getCellValue(row.getCell(1)).trim();
                officeTel = ExcelUtil.getCellValue(row.getCell(3)).trim();

                if (!StringUtil.checkRegex(orgCode.trim(), StringUtil.codeRegex)) {
                    result += "机构代码格式错误；";
                }

                if (!StringUtil.checkRegex(parnetCode, StringUtil.parentcodeRegex)) {
                    result += "父机构代码格式错误；";
                }

                if (!StringUtil.checkRegex(orgName, StringUtil.nameRegex)) {
                    result += "机构名称格式错误；";
                }

                if (StringUtils.isNotEmpty(officeTel) && !StringUtil.checkRegex(officeTel, StringUtil.telRegex)) {
                    result += "电话号码格式错误；";
                }

                //存在异常
                if (!StringUtils.equals(result, "第" + (row.getRowNum() + 1) + "行：")) {
                    contentVal.add(result);
                }

                demo.setOrgCode(orgCode);
                demo.setOrgName(orgName);
                demo.setParentOrgCode(parnetCode);
                demo.setOfficeTel(officeTel);

                orgDemos.add(demo);
            }

            Set<String> tempList = new HashSet<String>();
            tempList.addAll(databaseOrg);
            tempList.addAll(excelOrg);

            //判断excel中的parentOrgCode是否在数据库中存在
            //判断excel中的parentOrgCode是否在本次excel中存在
            excelParent.removeAll(tempList);

            //判断excel中的orgCode是否在本次excel中重复
            List<String> repeatErr = StringUtil.checkListRepeat(excelOrg);

            //判断excel中的orgCode是否在数据库中存在
            excelOrg.retainAll(databaseOrg);

            //整理校验结果
            List<VanySoftValidationErr> validationlist = new ArrayList<VanySoftValidationErr>();
            VanySoftValidationErr orgExist = null;
            VanySoftValidationErr orgRepeat = null;
            VanySoftValidationErr parentNotExist = null;
            VanySoftValidationErr contentErr = null;

            if (contentVal != null && contentVal.size() > 0) {
                contentErr = new VanySoftValidationErr();
                contentErr.setField("内容校验结果");
                contentErr.setMessage(contentVal.toArray(new String[contentVal.size()]));
                validationlist.add(contentErr);
            }

            if (excelOrg != null && excelOrg.size() > 0) {
                orgExist = new VanySoftValidationErr();
                orgExist.setField("组织机构存在");
                orgExist.setMessage(excelOrg.toArray(new String[excelOrg.size()]));
                validationlist.add(orgExist);
            }


            if (repeatErr != null && repeatErr.size() > 0) {
                orgRepeat = new VanySoftValidationErr();
                orgRepeat.setField("excel中组织机构重复");
                orgRepeat.setMessage(repeatErr.toArray(new String[repeatErr.size()]));
                validationlist.add(orgRepeat);
            }

            if (excelParent != null && excelParent.size() > 0) {
                parentNotExist = new VanySoftValidationErr();
                parentNotExist.setField("父机构不存在");
                parentNotExist.setMessage(excelParent.toArray(new String[excelParent.size()]));
                validationlist.add(parentNotExist);
            }

            if (validationlist != null && validationlist.size() > 0) {
                throw new VanySoftValidationException(MessageCodeConstant.ExcelException.VALIDATION_RESULT, validationlist);
            } else {
                //没有异常就提交
                orgService.addOrgBatch(orgDemos);
            }
        }

        return new JSONResponse(MessageCodeConstant.RTN_CODE_SUCCESS);

    }

    /**
     * Function Name               excelExportOrg
     *
     * @param response
     * @param orgCode
     * @throws InvalidFormatException
     * @throws VanySoftBaseException
     * @description Excel导出组织机构
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年6月8日 下午2:27:32           SharpClaw_x      Initial
     * *********************************************************************
     */
    @RequestMapping(value = "/export", method = RequestMethod.GET)
    public JSONResponse excelExportOrg(@SessionUser UserInfo userInfo, HttpServletRequest request, HttpServletResponse response, String orgCode) throws VanySoftBaseException {
        List<Map<String, Object>> sheetList = new ArrayList<Map<String, Object>>();
        Map<String, Object> sheet1 = new HashMap<String, Object>();

        String[] header1 = {"部门编号", "部门名称", "父部门编号", "电话号码"};
        String[] rowkey1 = {"orgCode", "orgName", "parentOrgCode", "officeTel"};

        List<Map<String, Object>> orgList = new ArrayList<Map<String, Object>>();
        ;
        if (userInfo != null) {
            orgList = orgService.queryOrgList(orgCode, userInfo.getId());
        }

        String fileName = orgCode + "部门导出";
        if (orgList != null && orgList.size() > 0) {
            fileName = String.valueOf(orgList.get(0).get("orgName"));
        }

        sheet1.put("title", fileName);
        sheet1.put("rows", orgList);
        sheet1.put("rowkey", rowkey1);
        sheet1.put("header", header1);
        sheetList.add(sheet1);
        Workbook workbook = ExcelUtil.exportExample(sheetList);

        OutputStream toClient = null;
        try {
            fileName = URLEncoder.encode(fileName, "UTF-8");
            // 清空response
            response.reset();
            // 设置response的Header
            response.setContentType("application/octet-stream");
            response.addHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
            response.setContentType("text/html;charset=UTF-8");
            toClient = new BufferedOutputStream(response.getOutputStream());
            workbook.write(toClient);
            toClient.flush();
        } catch (IOException ex) {
            throw new VanySoftBaseException(MessageCodeConstant.ExcelException.DOWNLOAD_FAIL);
        } finally { // close() 方法在finally模块中处理
            try {
                if (toClient != null) {
                    toClient.close();
                }
            } catch (IOException e) {
                throw new VanySoftBaseException(MessageCodeConstant.ExcelException.DOWNLOAD_FAIL);
            }
        }

        return new JSONResponse();
    }


    /**
     * Function Name               queryAllOrgList
     *
     * @return
     * @throws VanySoftBaseException
     * @description (消息中心发送部门 - 加载所有)
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年8月29日 上午11:02:06          SharpClaw_x                     Initial
     * *********************************************************************
     */
    @RequestMapping(value = "/queryAllOrgList", method = RequestMethod.GET)
    public JSONResponse queryAllOrgList(@SessionUser UserInfo userInfo) throws VanySoftBaseException {
        List<Map> tree = orgService.queryAllOrgList();
        return new JSONResponse(MessageCodeConstant.RTN_CODE_SUCCESS, tree);
    }
//	/**
//	 * Function Name               queryLoadOrgList                                   
//	 * @param request
//	 * @return
//	 * @throws NumberFormatException
//	 * @throws VanySoftBaseException          		             
//	 * @description 组织-功能授权,组织机构树加载
//	 * Modify History:              Date             Programmer       Notes
//	 *                            ---------        ---------------  ---------
//	 *                      2017年6月6日 下午2:34:08          SharpClaw_x                     Initial
//	 **********************************************************************
//	 */
//	@RequestMapping(value="/loadOrgInfo",method={RequestMethod.GET})
//	public JSONResponse loadOrgInfo(HttpServletRequest request) throws NumberFormatException, VanySoftBaseException{
//		RedisUserInfo redisUserInfo = getLoginUser(request);
//		String loginUserCode = redisUserInfo.getUserId();
//		List<Map<String,Object>> listMap =  orgService.loadOrgInfo(loginUserCode);
//		return new JSONResponse(listMap);
//	}
//
//	/**
//	 * Function Name               loadFunctionByOrgCode                                   
//	 * @param request
//	 * @return
//	 * @throws NumberFormatException
//	 * @throws VanySoftBaseException          		             
//	 * @description 根据当前登录用户代码,所选机构编号查询待分配,已分配功能权限
//	 * Modify History:              Date             Programmer       Notes
//	 *                            ---------        ---------------  ---------
//	 *                      2017年6月6日 下午8:02:59          SharpClaw_x                     Initial
//	 **********************************************************************
//	 */
//	@RequestMapping(value="/loadFunctionByOrgCode",method = RequestMethod.GET)
//	public JSONResponse loadFunctionByOrgCode(HttpServletRequest request) throws VanySoftBaseException{
//		RedisUserInfo redisUserInfo = getLoginUser(request);
//		String loginUserCode = redisUserInfo.getUserId();
//		String orgCode=request.getParameter("orgCode");
//		Map<String,Object> map = orgService.loadFunctionByOrgCode(loginUserCode,orgCode);
//		return new JSONResponse(map);
//	}
//	
//	/**
//	 * Function Name               modifyOrgFunctionAllotAndRemove                                   
//	 * @param request
//	 * @return          		             
//	 * @description 组织机构功能权限分配与移除
//	 * Modify History:              Date             Programmer       Notes
//	 *                            ---------        ---------------  ---------
//	 *                      2017年6月6日 下午8:29:56          SharpClaw_x                     Initial
//	 **********************************************************************
//	 */
//	@RequestMapping(value="/modifyOrgFunctionAllotAndRemove",method = RequestMethod.POST)
//	public JSONResponse modifyOrgFunctionAllotAndRemove(HttpServletRequest request){
//		String orgCode=request.getParameter("orgCode");
//		String functionCodes=request.getParameter("functionCodes");
//		orgService.modifyOrgFunctionAllotAndRemove(orgCode,functionCodes);
//		return new JSONResponse();
//		
//	}
//	
}
